#!/usr/bin/env node

require('dotenv').config();
const Client = require('ftp');
const chalk = require('chalk');
const net = require('net');

class FTPDiagnostic {
    constructor() {
        this.host = process.env.FTP_HOST;
        this.port = parseInt(process.env.FTP_PORT) || 21;
        this.user = process.env.FTP_USER;
        this.password = process.env.FTP_PASSWORD;
    }

    async run() {
        console.log(chalk.blue('🔍 FTP连接诊断工具'));
        console.log(chalk.gray('=' .repeat(50)));
        
        console.log(chalk.cyan(`目标服务器: ${this.host}:${this.port}`));
        console.log(chalk.cyan(`用户名: ${this.user}`));
        console.log('');

        // 步骤1: 测试基本网络连接
        await this.testNetworkConnection();
        
        // 步骤2: 测试FTP端口
        await this.testFTPPort();
        
        // 步骤3: 测试FTP协议连接
        await this.testFTPProtocol();
        
        // 步骤4: 测试不同配置
        await this.testDifferentConfigs();
        
        console.log(chalk.blue('\n🔧 建议的解决方案:'));
        this.showSuggestions();
    }

    async testNetworkConnection() {
        console.log(chalk.yellow('1. 测试基本网络连接...'));
        
        return new Promise((resolve) => {
            const socket = new net.Socket();
            const timeout = 5000;
            
            socket.setTimeout(timeout);
            
            socket.on('connect', () => {
                console.log(chalk.green('  ✓ 网络连接正常'));
                socket.destroy();
                resolve(true);
            });
            
            socket.on('timeout', () => {
                console.log(chalk.red('  ❌ 连接超时'));
                socket.destroy();
                resolve(false);
            });
            
            socket.on('error', (err) => {
                console.log(chalk.red(`  ❌ 网络错误: ${err.message}`));
                socket.destroy();
                resolve(false);
            });
            
            socket.connect(this.port, this.host);
        });
    }

    async testFTPPort() {
        console.log(chalk.yellow('2. 测试FTP端口可访问性...'));
        
        try {
            const { exec } = require('child_process');
            const command = process.platform === 'win32' 
                ? `telnet ${this.host} ${this.port}`
                : `nc -zv ${this.host} ${this.port}`;
            
            return new Promise((resolve) => {
                exec(command, { timeout: 5000 }, (error, stdout, stderr) => {
                    if (error) {
                        console.log(chalk.red(`  ❌ 端口测试失败: ${error.message}`));
                        resolve(false);
                    } else {
                        console.log(chalk.green('  ✓ FTP端口可访问'));
                        resolve(true);
                    }
                });
            });
        } catch (error) {
            console.log(chalk.yellow('  ⚠ 无法执行端口测试'));
            return false;
        }
    }

    async testFTPProtocol() {
        console.log(chalk.yellow('3. 测试FTP协议连接...'));
        
        return new Promise((resolve) => {
            const client = new Client();
            let resolved = false;
            
            const timeout = setTimeout(() => {
                if (!resolved) {
                    console.log(chalk.red('  ❌ FTP协议连接超时'));
                    client.destroy();
                    resolved = true;
                    resolve(false);
                }
            }, 15000);
            
            client.on('ready', () => {
                if (!resolved) {
                    console.log(chalk.green('  ✓ FTP认证连接成功'));
                    clearTimeout(timeout);
                    client.end();
                    resolved = true;
                    resolve(true);
                }
            });
            
            client.on('error', (error) => {
                if (!resolved) {
                    console.log(chalk.red(`  ❌ FTP连接失败: ${error.message}`));
                    clearTimeout(timeout);
                    resolved = true;
                    resolve(false);
                }
            });
            
            client.connect({
                host: this.host,
                port: this.port,
                user: this.user,
                password: this.password,
                debug: (msg) => console.log(chalk.gray(`    调试: ${msg}`))
            });
        });
    }

    async testDifferentConfigs() {
        console.log(chalk.yellow('4. 测试不同配置...'));
        
        const configs = [
            { name: '被动模式 + 长超时', passive: true, timeout: 60000 },
            { name: '主动模式 + 长超时', passive: false, timeout: 60000 },
            { name: '被动模式 + 短超时', passive: true, timeout: 15000 },
            { name: '主动模式 + 短超时', passive: false, timeout: 15000 },
        ];

        for (const config of configs) {
            console.log(chalk.gray(`  测试: ${config.name}...`));
            
            const success = await this.testSingleConfig(config);
            if (success) {
                console.log(chalk.green(`    ✓ ${config.name} 连接成功！`));
                console.log(chalk.yellow(`    建议配置: FTP_PASSIVE=${config.passive} FTP_TIMEOUT=${config.timeout}`));
                return true;
            }
        }
        
        return false;
    }
    
    async testSingleConfig(config) {
        return new Promise((resolve) => {
            const client = new Client();
            let resolved = false;
            
            const timeout = setTimeout(() => {
                if (!resolved) {
                    console.log(chalk.red(`    ❌ ${config.name} 连接超时`));
                    client.destroy();
                    resolved = true;
                    resolve(false);
                }
            }, config.timeout + 5000);
            
            client.on('ready', () => {
                if (!resolved) {
                    clearTimeout(timeout);
                    
                    // 测试数据连接
                    client.pwd((err, dir) => {
                        if (err) {
                            console.log(chalk.red(`    ❌ ${config.name} 数据连接失败: ${err.message}`));
                            resolved = true;
                            resolve(false);
                        } else {
                            console.log(chalk.green(`    ✓ ${config.name} 数据连接成功`));
                            resolved = true;
                            resolve(true);
                        }
                        client.end();
                    });
                }
            });
            
            client.on('error', (error) => {
                if (!resolved) {
                    console.log(chalk.red(`    ❌ ${config.name} 失败: ${error.message}`));
                    clearTimeout(timeout);
                    resolved = true;
                    resolve(false);
                }
            });
            
            client.connect({
                host: this.host,
                port: this.port,
                user: this.user,
                password: this.password,
                passive: config.passive,
                pasvTimeout: config.timeout,
                connTimeout: config.timeout
            });
        });
    }

    showSuggestions() {
        console.log(chalk.cyan('• 检查FTP服务器是否正在运行'));
        console.log(chalk.cyan('• 确认FTP账户用户名和密码正确'));
        console.log(chalk.cyan('• 检查服务器防火墙设置，确保21端口开放'));
        console.log(chalk.cyan('• 检查本地防火墙或杀毒软件是否阻止连接'));
        console.log(chalk.cyan('• 确认你的IP地址在服务器允许列表中'));
        console.log(chalk.cyan('• 尝试使用FTP客户端工具 (如FileZilla) 测试连接'));
        console.log(chalk.cyan('• 联系服务器管理员确认FTP服务配置'));
        
        console.log(chalk.yellow('\n建议的.env配置调整:'));
        console.log(chalk.gray('FTP_PASSIVE=false  # 如果被动模式失败'));
        console.log(chalk.gray('FTP_TIMEOUT=60000  # 增加超时时间'));
        console.log(chalk.gray('FTP_DEBUG=true     # 启用详细日志'));
    }
}

if (require.main === module) {
    const diagnostic = new FTPDiagnostic();
    diagnostic.run().catch(console.error);
}

module.exports = FTPDiagnostic;